package com.fy.fyspace.task;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.fy.fyspace.mapper.PictureMapper;
import com.fy.fyspace.model.entity.Picture;
import com.fy.fyspace.model.entity.PictureHotness;
import com.fy.fyspace.service.PictureHotnessService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 热度计算定时任务
 * 设计模式：定时任务模式
 * 作用：定时执行热度计算和历史分数更新
 * 
 * @author fwq
 * @since 2024-12-19
 */
@Slf4j
@Component
public class HotnessCalculationTask {
    
    @Autowired
    private PictureHotnessService pictureHotnessService;
    
    @Autowired
    private PictureMapper pictureMapper;
    
    /**
     * 每日凌晨2点执行全量热度计算
     * 设计模式：定时任务模式
     * 作用：每天自动计算所有图片的热度分数
     */
    @Scheduled(cron = "0 0 2 * * ?")
    public void dailyHotnessCalculation() {
        log.info("开始执行每日热度计算定时任务");
        
        try {
            // 计算所有图片的热度
            List<PictureHotness> hotnessList =
                pictureHotnessService.calculateAllHotness("standardHotnessStrategy");
            
            log.info("每日热度计算完成，成功计算数量: {}", hotnessList.size());
            
        } catch (Exception e) {
            log.error("每日热度计算失败", e);
        }
    }
    
    /**
     * 每日凌晨3点执行历史分数更新
     * 设计模式：定时任务模式
     * 作用：每天自动更新所有图片的历史分数
     */
    @Scheduled(cron = "0 0 3 * * ?")
    public void dailyHistoricalScoreUpdate() {
        log.info("开始执行每日历史分数更新定时任务");
        
        try {
            // 获取所有有效图片的ID
            LambdaQueryWrapper<Picture> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(Picture::getIsDelete, 0) // 未删除的图片
                   .eq(Picture::getReviewStatus, 1) // 审核通过的图片
                   .select(Picture::getId); // 只查询ID字段
            
            List<Picture> pictures = pictureMapper.selectList(wrapper);
            List<Long> pictureIds = pictures.stream()
                    .map(Picture::getId)
                    .collect(Collectors.toList());
            
            if (!pictureIds.isEmpty()) {
                // 批量更新历史分数
                int successCount = pictureHotnessService.batchUpdateHistoricalScores(pictureIds);
                log.info("每日历史分数更新完成，成功更新数量: {}/{}", successCount, pictureIds.size());
            } else {
                log.info("没有找到需要更新历史分数的图片");
            }
            
        } catch (Exception e) {
            log.error("每日历史分数更新失败", e);
        }
    }
    
    /**
     * 每周日凌晨4点执行周度热度计算
     * 设计模式：定时任务模式
     * 作用：每周自动计算周度热度排行
     */
    @Scheduled(cron = "0 0 4 ? * SUN")
    public void weeklyHotnessCalculation() {
        log.info("开始执行周度热度计算定时任务");
        
        try {
            // 计算所有图片的热度
            List<PictureHotness> hotnessList = 
                pictureHotnessService.calculateAllHotness("standardHotnessStrategy");
            
            log.info("周度热度计算完成，成功计算数量: {}", hotnessList.size());
            
        } catch (Exception e) {
            log.error("周度热度计算失败", e);
        }
    }
    
    /**
     * 每月1号凌晨5点执行月度热度计算
     * 设计模式：定时任务模式
     * 作用：每月自动计算月度热度排行
     */
    @Scheduled(cron = "0 0 5 1 * ?")
    public void monthlyHotnessCalculation() {
        log.info("开始执行月度热度计算定时任务");
        
        try {
            // 计算所有图片的热度
            List<PictureHotness> hotnessList = 
                pictureHotnessService.calculateAllHotness("standardHotnessStrategy");
            
            log.info("月度热度计算完成，成功计算数量: {}", hotnessList.size());
            
        } catch (Exception e) {
            log.error("月度热度计算失败", e);
        }
    }
} 